package com.xyz.service;

import com.free.common.vo.ResultModel;
import com.free.utils.RegexUtils;
import com.xyz.dao.logic.CCustomerOperLogLogic;
import com.xyz.dao.logic.CustomerLogic;
import com.xyz.domain.constants.EhCacheConstants;
import com.xyz.domain.ext.EnumOperLogCategory;
import com.xyz.domain.ext.EnumOperLogType;
import com.xyz.domain.model.CompleteUserModel;
import com.xyz.domain.table.CCustomer;
import com.xyz.domain.table.CCustomerOperLog;
import com.xyz.shiro.jwt.JwtTools;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;

@Service
public class CustomerService extends BaseService {

    @Autowired
    private CustomerLogic logic;

    @Autowired
    private CCustomerOperLogLogic operLogLogic;
    /**
     * 根据登录名获得用户信息
     * @param loginName
     * @return
     */
    public ResultModel getUserInfoByLoginName(String loginName){
        if(StringUtils.isEmpty(loginName)){
            return ResultModel.failure();
        }
        CCustomer customer = new CCustomer();
        fixCustomer(loginName, customer);
        List<CCustomer> lst = logic.list(customer, StringUtils.EMPTY);
        if(lst == null || lst.size() == 0 || lst.size() > 1){
            return ResultModel.failure();
        }
        return ResultModel.success(lst.get(0));
    }

    /**
     * 根据ID获得信息
     * @param custId
     * @return
     */
    public CCustomer getByKey(Integer custId){
        return logic.getByKey(custId);
    }

    /**
     * 完善信息
     * @param completeModel
     * @return
     */
    public ResultModel completeInfo(CompleteUserModel completeModel){
        return completeCheck(completeModel);
    }

    /**
     * JwtToken 生成
     * @param customer
     * @return
     */
    public String jwtTokenSign(CCustomer customer, String deviceType){
        return JwtTools.getInstance().sign(customer.getUserName(), deviceType, JwtTools.getInstance().getAccessTokenExpireTime());
    }

    /**
     * JwtToken 验证
     * @param tokenStr
     * @return
     */
    public boolean jwtTokenVerify(String tokenStr){
        return JwtTools.getInstance().verify(tokenStr);
    }

    /**
     * JwtToke 刷新
     * @param oldToken
     * @param userName
     * @param deviceType
     * @return
     */
    public String refershToken(String oldToken, String userName, String deviceType){
        if(JwtTools.getInstance().isTokenExpire(oldToken,JwtTools.getInstance().getRefreshTokenTime())){
           return JwtTools.getInstance().sign(userName, deviceType, JwtTools.getInstance().getAccessTokenExpireTime());
        }
        return StringUtils.EMPTY;
    }

    @Cacheable(cacheNames = EhCacheConstants.TokenCache, key = "#userName")
    public CCustomer getByMobile(String userName){
        return logic.selectByMobile(userName);
    }

    /**
     * 根据Token 获得用户信息
     * @param token
     * @return
     */
    public CCustomer getCustomerByToken(String token){
        if(!jwtTokenVerify(token)){
            return null;
        }
        if(JwtTools.getInstance().isTokenExpire(token, JwtTools.getInstance().getAccessTokenExpireTime())){
            return null;
        }
        String userName = JwtTools.getInstance().getClaim(token,JwtTools.JWT_ACCOUNT);
        CCustomer customer = getByMobile(userName);
        return customer;
    }

    @Transactional
    public ResultModel updateCustomerInfo(String enumUserType, CompleteUserModel customerInfo){
        CCustomer customer = getCurrentUser();

        EnumOperLogType type = EnumOperLogType.getByKey(enumUserType);
        if(type == null){
            return ResultModel.failure(null,"不存在该操作");
        }

        CCustomerOperLog operLog = operLogLogic.addOperInfo(EnumOperLogCategory.REGIST.getName(),type.getKey(), customer.getId());
        if(operLog == null || operLog.getId() == 0){
            return ResultModel.failure();
        }

        // 完善信息
        if(enumUserType.equals(EnumOperLogType.UDPUSER_COMPLETE_INFO.getKey())){
            ResultModel res = completeCheck(customerInfo);
            if(!res.isSuccess()){
              return res;
            }
            BeanUtils.copyProperties(customerInfo, customer);
        }
        // 完善银行卡信息
//        else if(enumUserType.equals(EnumOperLogType.UDPUSER_BANKCARD.getKey())){
//            ResultModel res = bankCardCheck(customerInfo);
//            if(!res.isSuccess()){
//                return res;
//            }
//            customer
//        }
        // 完成微信信息
        else if(enumUserType.equals(EnumOperLogType.UDPUSER_WECHAT.getKey())){
            ResultModel res = wechatCheck(customerInfo);
            if(!res.isSuccess()){
                return res;
            }
            customer.setWxOpenId(customerInfo.getWxOpenId());
            customer.setWxPayAccnt(customerInfo.getWxPayAccnt());
        }
        int udpRes = logic.udpCustomerInfo(customer);
        if(udpRes == 0){
            return ResultModel.failure();
        }
        cahceEvict(EhCacheConstants.TokenCache, customer.getMobile());
        return ResultModel.success();
    }

    private ResultModel completeCheck(CompleteUserModel completeUserModel){
        if(StringUtils.isEmpty(completeUserModel.getAddress())){
            return ResultModel.failure(null,"地址必须输入");
        }
        if(StringUtils.isEmpty(completeUserModel.getBirthday())){
            return ResultModel.failure(null,"生日必须输入");
        }
        if(StringUtils.isEmpty(completeUserModel.getNickName())){
            return ResultModel.failure(null,"生日必须输入");
        }
//        if(StringUtils.isEmpty(completeUserModel.getQq())){
//            return ResultModel.failure(null,"QQ必须输入");
//        }
        if(StringUtils.isEmpty(completeUserModel.getUserName())){
            return ResultModel.failure(null,"姓名必须输入");
        }
        return ResultModel.success();
    }

    private ResultModel bankCardCheck(CompleteUserModel completeUserModel){
        if(StringUtils.isEmpty(completeUserModel.getBankCard())){
            return ResultModel.failure(null, "银行卡必须输入");
        }
        return ResultModel.success();
    }

    private ResultModel wechatCheck(CompleteUserModel completeUserModel){
        if(StringUtils.isEmpty(completeUserModel.getWxOpenId())){
            return ResultModel.failure(null, "没有获得微信授权信息");
        }
        if(StringUtils.isEmpty(completeUserModel.getWxPayAccnt())){
            return ResultModel.failure(null, "没有获得微信支付账号");
        }
        return ResultModel.success();
    }

    public void fixCustomer(String loginName, CCustomer customer){
        LoginNameType lgnType = getLoginType(loginName);
        if(lgnType == LoginNameType.Mobile){
            customer.setMobile(loginName);
        }else if(lgnType == LoginNameType.Email){
            customer.setEmalAccnt(loginName);
        }else{
            throw new RuntimeException("账号信息不正确");
        }
    }

    public LoginNameType getLoginType(String loginName){
        if(RegexUtils.isMobileSimple(loginName)){
            return LoginNameType.Mobile;
        }
        if(RegexUtils.isEmail(loginName)){
            return LoginNameType.Email;
        }
        return null;
    }

    public enum LoginNameType {
        Mobile,Email
    }
}
